
// Define PacketType enumeration
const PacketType = {
  PINGREQ: "PINGREQ",
  PINGRESP: "PINGRESP",
  REGISTER: "REGISTER",
  Reg_ACK: "Reg_ACK",
  SUBSCRIBE: "SUBSCRIBE",
  SUB_ACK: "SUB_ACK",
  UNSUB_ACK: "UNSUB_ACK",
  PUBLISH: "PUBLISH",
  PUBLISH_ACK: "PUBLISH_ACK"
};

// Define DeviceType enumeration
const DeviceType = {
  // Define your device types here

};

// Define Header class
class Header {
  constructor() {
    this.packetType = null;
    this.deviceType = null;
  }

  setPacketType(packetType) {
    this.packetType = packetType;
  }

  setDeviceType(deviceType) {
    this.deviceType = deviceType;
  }
}

// Define Body class
class Body {
  constructor() {
    this.messageId = parseInt(Math.random()*5000);
  }

  setName(name) {
    this.name = name;
  }

  setPassword(password) {
    this.password = password;
  }

  setResponseCode(responseCode) {
    this.responseCode = responseCode;
  }

  setPacketTime(packetTime) {
    this.packetTime = packetTime;
  }

  setSubTopics(topics) {
    this.subTopics = topics;
  }

  setTopic(topic) {
    this.topic = topic;
  }

  setPushSerialType(pushSerialType) {
    this.pushSerialType = pushSerialType;
  }

  setMessageId(messageId) {
    this.messageId = messageId;
  }

  setMsg(msg) {
    this.msg = msg;
  }
}

// Define PushPacket class
export default class PushPacket {
  constructor() {
    this.header = new Header();
    this.body = new Body();
  }

  ping(deviceType) {
    this.header.setPacketType(PacketType.PINGREQ);
    this.header.setDeviceType(deviceType);
    return this;
  }

  pong(deviceType) {
    this.header.setPacketType(PacketType.PINGRESP);
    this.header.setDeviceType(deviceType);
    return this;
  }

  register(name, password, deviceType) {
    this.header.setPacketType(PacketType.REGISTER);
    this.header.setDeviceType(deviceType);
    this.body.setName(name);
    this.body.setPassword(password);
    this.body.keepAliveTimer = 120;
    return this;
  }

  registerAck(deviceType, mqttConnectReturnCode) {
    this.header.setPacketType(PacketType.Reg_ACK);
    this.header.setDeviceType(deviceType);
    this.body.setResponseCode(mqttConnectReturnCode);
    this.body.setPacketTime(Date.now());
    return this;
  }

  subscribe(deviceType, topics) {
    this.header.setPacketType(PacketType.SUBSCRIBE);
    this.header.setDeviceType(deviceType);
    this.body.setSubTopics(topics);
    this.body.setPacketTime(Date.now());
    return this;
  }

  subscribeAck(deviceType) {
    this.header.setPacketType(PacketType.SUB_ACK);
    this.header.setDeviceType(deviceType);
    return this;
  }

  unSubscribeAck(deviceType) {
    this.header.setPacketType(PacketType.UNSUB_ACK);
    this.header.setDeviceType(deviceType);
    return this;
  }

  push(deviceType, topic, msg) {
    this.header.setPacketType(PacketType.PUBLISH);
    this.header.setDeviceType(deviceType);
    this.body = new Body();
    this.body.setMessageId(Math.floor(Math.random() * 1000)); // Random message ID
    this.body.setTopic(topic);
    this.body.setMsg(msg);
    return this;
  }

  pushAck(deviceType, messageId) {
    this.header.setPacketType(PacketType.PUBLISH_ACK);
    this.header.setDeviceType(deviceType);
    this.body.setMessageId(messageId);
    return this;
  }

  toJson() {
    return JSON.stringify(this);
  }
}

